#ifndef FFTWENGINE_H
#define FFTWENGINE_H

#include <assert.h>
#include <fftw3.h>
#include <boost/shared_ptr.hpp>

#include "fftwallocator.h"

/**
* Class FFTWEngine represents a real-to-real Fourie transformation.
* The transformation must be applied only for fixed size array.
* @note for better perfomance use arrays with size is power 2.
* Arrays for input data and results must be allocated via AllocateSignal method.
*/
class FFTWEngine
{
public:
  typedef boost::shared_ptr<FFTWRealSignal>	RealSignalPtr;

  inline FFTWEngine(unsigned int sz)
  {
    size = 0;
    plan = 0;
    setSize(sz);
  };

  inline ~FFTWEngine()
  {
    fftw_destroy_plan(plan);
  };

  /**
  *
  */
  inline RealSignalPtr AllocateSignal()
  {
    return RealSignalPtr( new FFTWRealSignal(size) );
  };
  
  /**
  * The main method of the class.
  * It calculates Fourie transformation.
  * @param in shared pointer on an input data
  * @param out shared pointer on an output data
  */
  inline void execute( RealSignalPtr in, RealSignalPtr out )
  {
    assert(size==in->size());
    assert(size==out->size());

    fftw_execute_r2r( plan, &(in->operator[](0)), &(out->operator[](0)) );
  };

  /**
  * This methom setes a new size for input/output data arrays.
  * @note Will be carrefully! After size changing you can't use already allocated RealSignalPtr!
  * @param sz new size;
  */
  void setSize( unsigned int sz );

private:
  fftw_plan	plan; /** It is handler for fftw3 engine.*/
  unsigned int	size; /** Current size of array that can be processed */
};

#endif //FFTWENGINE_H
